package org.jflame.context.security;

import org.jflame.commons.reflect.SPIFactory;
import org.jflame.context.security.mask.DataMaskPolicy;
import org.jflame.context.security.satoken.SaTokenSecurityService;
import org.jflame.context.security.shiro.ShiroSecurityService;
import org.jflame.context.security.springsecurity.SpSecurityService;

import java.util.Collection;

public class SecurityFacade {

    private volatile static SecurityService securityService;
    private static DataMaskPolicy dataMaskPolicy;

    private SecurityFacade() {
    }

    static {
        try {
            securityService = SPIFactory.getBean(SecurityService.class);
        } catch (Throwable e) {
            try {
                securityService = new SpSecurityService();
            } catch (Throwable e1) {
                try {
                    securityService = new ShiroSecurityService();
                } catch (Throwable e2) {
                    securityService = new SaTokenSecurityService();
                }
            }
        }
    }

    public static boolean hasAuthority(String authority) {
        return securityService.hasAuthority(authority);
    }

    /**
     * 返回认证的主体对象
     * 
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T getPrincipal() {
        return (T) securityService.getPrincipal();
    }

    /**
     * 判断当前用户是否有指定的任意一个权限
     * 
     * @param authority 权限标识
     * @return
     */
    public static boolean hasAnyAuthority(String... authority) {
        return securityService.hasAnyAuthority(authority);
    }

    /**
     * 判断：当前账号是否拥有指定角色, 返回 true 或 false
     *
     * @param role 角色
     * @return
     */
    public static boolean hasRole(String role) {
        return securityService.hasRole(role);
    }

    public static boolean hasAnyRole(String... roles) {
        return securityService.hasAnyRole(roles);
    }

    public static boolean hasAllRoles(Collection<String> roleSet) {
        return securityService.hasAllRoles(roleSet);
    }

    public static synchronized void setSecurityService(SecurityService securityService) {
        if (SecurityFacade.securityService == null) {
            SecurityFacade.securityService = securityService;
        }
    }

    public static void setDataMaskPolicy(DataMaskPolicy dataMaskPolicy) {
        SecurityFacade.dataMaskPolicy = dataMaskPolicy;
    }

    /**
     * 是否需要数据脱敏
     * 
     * @param dataId 数据权限标识
     * @return 需要脱敏返回true
     */
    public static boolean requireMask(String dataId) {
        return dataMaskPolicy.requireMask(dataId);
    }
}
